home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / mac / files / dsp / 56000tar.z / 56000tar / 56000 / speech / adpcmns.asm < prev    next >
Assembly Source File  |  1991-11-26  |  55KB  |  1,556 lines

  1. ;
  2. ; This program originally available on the Motorola DSP bulletin board.
  3. ; It is provided under a DISCLAMER OF WARRANTY available from
  4. ; Motorola DSP Operation, 6501 Wm. Cannon Drive W., Austin, Tx., 78735.
  5. ;**************************************************************************
  6. ;
  7. ;   ADPCMNS.ASM       Full-Duplex 32-kbit/s Nonstandard CCITT ADPCM
  8. ;
  9. ; Version 1.0 - 8/9/90
  10. ;
  11. ; This program implements the algorithm defined in CCITT Recommendation
  12. ; G.721: "32 kbit/s Adaptive Differential Pulse Code Modulation" dated
  13. ; August 1986.  This code contains a real-time I/O interface for a
  14. ; hardware platform consisting of two DSP56000ADS boards, each connected
  15. ; to an MC145503 codec.
  16. ;
  17. ; Please refer to the file ADPCMNS.HLP for further information about
  18. ; this program.  Also refer to Motorola Application Report APR9/D for
  19. ; complete documentation.
  20. ;
  21. ;**************************************************************************
  22.  
  23.             OPT     CC,CEX
  24.                                                                          
  25. START       EQU     $0020
  26. PBDDR       EQU     $FFE2
  27. PBD         EQU     $FFE4
  28. PCC         EQU     $FFE1
  29. CRA         EQU     $FFEC
  30. CRB         EQU     $FFED
  31. SSISR       EQU     $FFEE
  32. SSIRX       EQU     $FFEF
  33. SSITX       EQU     $FFEF
  34. BCR         EQU     $FFFE
  35.  
  36.             ORG     X:$0000
  37.  
  38. ;******************** Encoder variables ***********************************
  39. ;   I = siii 0000 | 0000 0000 | 0000 0000 (ADPCM format)
  40. I_T         DS      1               ;ADPCM codeword
  41. ;   DQ = siii iiii | iiii iii.f | ffff ffff  (24SM)
  42. DQ_T        DS      1               ;Quantized difference signal
  43. ;   Y = 0iii i.fff | ffff ffff | ffff ffff  (23SM)
  44. Y_T         DS      1               ;Quantizer scale factor
  45. ;   AP = 0ii.f ffff | ffff ffff | ffff ffff  (23SM)
  46. AP_T        DS      1               ;Unlimited speed control parameter
  47. ;   AL = 0i.ff ffff | ffff ffff | ffff ffff  (23SM)
  48. AL_T        DS      1               ;Limited speed control parameter
  49.  
  50. ;******************** Decoder variables ***********************************
  51. I_R         DS      1               ;ADPCM codeword
  52. DQ_R        DS      1               ;Quantized difference signal
  53. Y_R         DS      1               ;Quantizer scale factor
  54. AP_R        DS      1               ;Unlimited speed control parameter
  55. AL_R        DS      1               ;Limited speed control parameter
  56.  
  57. ;******************** Temporary variables *********************************
  58. ;   IMAG = 0000 0000 | 0000 0000 | 0000 0iii.
  59. IMAG        DS      1               ;|I|
  60. ;   PKS1 = sXXX XXXX | XXXX XXXX | XXXX XXXX  (1TC)
  61. PKS1        DS      1               ;XOR of  PK0 & PK1
  62. ;   PKS2 = sXXX XXXX | XXXX XXXX | XXXX XXXX  (1TC)
  63. PKS2        DS      1               ;XOR of  PK0 & PK2
  64. DATAPTR_T   DS      1               ;Transmit data buffer pointer
  65. DATAPTR_R   DS      1               ;Receive data buffer pointer
  66.  
  67. ;******************** Table for quantizing DLN ****************************
  68. ; Used in QUAN routine
  69.  
  70. QUANTAB     DS      8
  71.  
  72. ;******************** Table for unquantizing I ****************************
  73. ; Used in RECONST
  74.  
  75. IQUANTAB    DS      8
  76.  
  77. ;******************** W(I) lookup table ***********************************
  78. ; Used in FUNCTW routine
  79.  
  80. WIBASE      DS      8
  81.  
  82. ;******************** F(I) lookup table ***********************************
  83. ; Used in FUNCTF routine
  84.  
  85. FIBASE      DS      8
  86.  
  87. ;******************** Table used in COMPRESS ******************************
  88.  
  89. TAB         DS      8
  90.  
  91. ;******************** Encoder data buffer *********************************
  92. ;   DQ = siii iiii | iiii iiii. | ffff ffff  (24TC)
  93. ;   SRn in same format
  94.  
  95. DATA_T      DSM     8                   ;8 word modulo buffer for data,
  96.                                         ; R2 is used as pointer, DATAPTR_T
  97.                                         ; points to start of buffer (DQ1)
  98.                                         ; at beginning of cycle
  99.  
  100. ;******************** Decoder data buffer *********************************
  101.  
  102. DATA_R      DSM     8                   ;8 word modulo buffer for data
  103.                                         ; (same format as DATA_T)
  104.  
  105.  
  106.             ORG     Y:$0000
  107. ;******************** Encoder variables ***********************************
  108. ;   SE = siii iiii | iiii iiii. | ffff ffff  (24TC)
  109. SE_T        DS      1               ;Signal estimate
  110. ;   SEZ = siii iiii | iiii iiii. | ffff ffff (24TC)
  111. SEZ_T       DS      1               ;Partial signal estimate
  112. ;   SR = siii iiii | iiii iiii. | ffff ffff  (24TC)
  113. SR_T        DS      1               ;Reconstructed signal
  114. ;   PK0 = sXXX XXXX | XXXX XXXX | XXXX XXXX  (1TC)
  115. PK0_T       DS      1               ;Sign of DQ + SEZ
  116. ;   PK1 = sXXX XXXX | XXXX XXXX | XXXX XXXX  (1TC)
  117. PK1_T       DS      1               ;Delayed sign of DQ + SEZ
  118. ;   DMS = 0iii. ffff | ffff ffff | ffff ffff  (23SM)
  119. DMS_T       DS      1               ;Short term average of F(I)
  120. ;   DML = 0iii. ffff | ffff ffff | ffff ffff  (23SM)
  121. DML_T       DS      1               ;Long term average of F(I)
  122. ;   TDP = i000 0000 | 0000 0000 | 0000 0000  (1TC)
  123. TDP_T       DS      1               ;Tone detect
  124. ;   TD = i000 0000 | 0000 0000 | 0000 0000  (1TC)
  125. TD_T        DS      1               ;Delayed tone detect
  126. ;   YU =  0iii i.fff | ffff ffff | ffff ffff  (23SM)
  127. YU_T        DS      1               ;Fast quantizer scale factor
  128. ;   YL =  0iii i.fff | ffff ffff | ffff ffff  (23SM)
  129. YL_T        DS      1               ;Slow quantizer scale factor
  130. ;   SIGPK = i000 0000 | 0000 0000 | 0000 0000  (1TC)
  131. SIGPK_T     DS      1               ;Sgn[p(k)] flag
  132. ;   A2P = si.ff ffff | ffff ffff | ffff ffff (24TC)
  133. A2P_T       DS      1               ;Second order predictor coef
  134. ;   TR = i000 0000 | 0000 0000 | 0000 0000  (1TC)
  135. TR_T        DS      1               ;Transition detect
  136. ;   S = psss qqqq | 0000 0000 | 0000 0000 (PCM log format)
  137. S_T         DS      1               ;Input PCM signal
  138.  
  139. ;******************** Decoder variables ***********************************
  140. SE_R        DS      1               ;Signal estimate
  141. SEZ_R       DS      1               ;Partial signal estimate
  142. SR_R        DS      1               ;Reconstructed signal
  143. PK0_R       DS      1               ;Sign of DQ + SEZ
  144. PK1_R       DS      1               ;Delayed sign of DQ + SEZ
  145. DMS_R       DS      1               ;Short term average of F(I)
  146. DML_R       DS      1               ;Long term average of F(I)
  147. TDP_R       DS      1               ;Tone detect
  148. TD_R        DS      1               ;Delayed tone detect
  149. YU_R        DS      1               ;Fast quantizer scale factor
  150. YL_R        DS      1               ;Slow quantizer scale factor
  151. SIGPK_R     DS      1               ;Sgn[p(k)] flag
  152. A2P_R       DS      1               ;Second order predictor coef
  153. TR_R        DS      1               ;Transition detect
  154. SP_R        DS      1               ;Output PCM signal
  155.  
  156. ;******************** Temporary variables *********************************
  157. DQMAG       DS      1               ;|DQ|
  158. SL_T        DS      1               ;PCM input for encoder
  159. LAW         DS      1               ;PCM mode select
  160.  
  161. ;******************** Shift constant lookup table *************************
  162. ; Shift constants used for doing left or right shifts by multiplying by a
  163. ; power of 2.
  164.  
  165. RSHFT       DS      24
  166. LSHFT
  167.  
  168. ;******************** Encoder coef. buffer ********************************
  169. ;   Bn = si.ff ffff | ffff ffff | ffff ffff (24TC)
  170. ;   An in same format
  171.                                     ;8 word modulo buffer for coefs.,
  172.                                     ; R6 is used as pointer
  173. COEF_T      DSM     8               ;B1
  174.                                     ;B2
  175.                                     ;B3
  176.                                     ;B4
  177.                                     ;B5
  178.                                     ;B6
  179.                                     ;A1
  180.                                     ;A2
  181.  
  182. ;******************** Decoder coef. buffer ********************************
  183.                                     ;8 locations for coef. queue
  184.                                     ; (same format as COEF_T)
  185. COEF_R      DSM     8               ;B1
  186.                                     ;B2
  187.                                     ;B3
  188.                                     ;B4
  189.                                     ;B5
  190.                                     ;B6
  191.                                     ;A1
  192.                                     ;A2
  193.  
  194.             PAGE
  195.  
  196.             ORG     P:$0000
  197.             JMP     START
  198.  
  199.             ORG     P:START
  200.  
  201.         MOVEC   #$06,OMR            ;Set DE=1
  202.         CLR     A
  203.         MOVEP   A,X:BCR             ;Set BCR for 0 wait states
  204.         JSR     INIT
  205.  
  206. ;**************************************************************************
  207. ;
  208. ; Poll SSI for receiver data available.  Note that the SSI transmit and
  209. ; receive are synchronous.
  210. ;
  211. ;**************************************************************************
  212.  
  213. IOWAIT  JCLR    #7,X:SSISR,IOWAIT   ;Wait for SSIRX full
  214.         MOVE    Y:SP_R,A            ;Get decoder output
  215.         MOVEP   A,X:SSITX           ;Send PCM output to CODEC
  216.         MOVEP   X:SSIRX,A           ;Get input sample
  217.         MOVE    A,Y:S_T             ;Save PCM input for encoder
  218.  
  219. ;**************************************************************************
  220. ;
  221. ;   Encoder
  222. ;
  223. ;**************************************************************************
  224.  
  225. ENCODE  MOVE    X:DATAPTR_T,R2      ;Set data pointer to DQ1EXP
  226.         MOVE    #COEF_T,R6          ;Set coef pointer to B1
  227.         JSR     <PRDICT             ;(FMULT,ACCUM)
  228.         MOVE    B,Y:SEZ_T
  229.         MOVE    A,Y:SE_T
  230.  
  231.         MOVE    X:AP_T,A
  232.         MOVE    Y:YL_T,Y1
  233.         MOVE    Y:YU_T,Y0
  234.         JSR     <LIMAMIX            ;(LIMA,MIX)
  235.         MOVE    X1,X:AL_T
  236.         MOVE    A,X:Y_T
  237.  
  238. ;********************************************
  239. ; Get encoder input (PCM data)
  240.  
  241.         MOVE    Y:S_T,A
  242.  
  243. ;********************************************
  244.  
  245.         MOVE    Y:SE_T,B
  246.         MOVE    X:Y_T,Y0
  247.         JSR     <CONVERT            ;(EXPAND,SUBTA,LOG,SUBTB,QUAN)
  248.         MOVE    A,X:I_T
  249.         
  250. ;********************************************
  251. ; Output ADPCM word
  252.  
  253.         MOVE    A,X1    Y:RSHFT+20,Y0
  254.         MPY     Y0,X1,A             ;Shift ADPCM word to LSB's
  255.         MOVEP   A1,X:PBD            ;Put output on PB0..3
  256.         MOVE    X:I_T,A
  257.  
  258. ;********************************************
  259.  
  260.         MOVE    X:Y_T,B
  261.         JSR     <IQUAN              ;(RECONST,ADDA,ANTILOG)
  262.         MOVE    A1,X:DQ_T
  263.  
  264.         MOVE    Y:TD_T,A
  265.         MOVE    Y:YL_T,B
  266.         JSR     <TRANS              ;(TRANS)
  267.         MOVE    A1,Y:TR_T
  268.  
  269.         MOVE    Y:SE_T,B
  270.         MOVE    X:DQ_T,A
  271.         MOVE    Y:SEZ_T,X0
  272.         MOVE    #PK1_T,R0
  273.         JSR     <ADDBC              ;(ADDB,ADDC)
  274.         MOVE    X1,Y:SR_T
  275.         MOVE    B1,Y:SIGPK_T
  276.  
  277.         MOVE    X:DQ_T,Y0
  278.         JSR     <UPB                ;(XOR,UPB)
  279.  
  280.         MOVE    Y:SIGPK_T,X0
  281.         JSR     <UPA2               ;(UPA2,LIMC)
  282.         MOVE    A,Y:A2P_T
  283.         MOVE    A,Y:(R6)-           ;Save A2P to A2
  284.  
  285.         MOVE    Y:SIGPK_T,X1
  286.         MOVE    Y:A2P_T,X0
  287.         JSR     <UPA1               ;(UPA1,LIMD)
  288.  
  289.         MOVE    X:DQ_T,A
  290.         MOVE    Y:SR_T,B
  291.         JSR     <FLOAT              ;(FLOATA,FLOATB)
  292.  
  293.         MOVE    Y:A2P_T,B
  294.         MOVE    Y:TR_T,Y0
  295.         JSR     <TONE               ;(TONE,TRIGB)
  296.         MOVE    Y1,Y:TDP_T
  297.         MOVE    A,Y:TD_T
  298.  
  299.         MOVE    Y:DMS_T,Y0
  300.         MOVE    Y:DML_T,Y1
  301.         JSR     <FUNCTF             ;(FUNCTF,FILTA,FILTB)
  302.         MOVE    A,Y:DMS_T
  303.         MOVE    B,Y:DML_T
  304.  
  305.         MOVE    Y:TDP_T,X1
  306.         MOVE    X:Y_T,Y1
  307.         JSR     <SUBTC              ;(SUBTC)
  308.  
  309.         MOVE    X:AP_T,X1
  310.         MOVE    Y:TR_T,Y1
  311.         JSR     <FILTC              ;(FILTC,TRIGA)
  312.         MOVE    A1,X:AP_T
  313.  
  314.         MOVE    X:Y_T,Y0
  315.         MOVE    Y:YL_T,Y1
  316.         JSR     <FUNCTW             ;(FUNCTW,FILTD,LIMB,FILTE)
  317.         MOVE    X0,Y:YU_T
  318.         MOVE    A1,Y:YL_T
  319.  
  320.         MOVE    R2,X:DATAPTR_T      ;Save transmit data pointer
  321.  
  322. ;**************************************************************************
  323. ;
  324. ;   Decoder
  325. ;
  326. ;**************************************************************************
  327.  
  328. DECODE  MOVE    X:DATAPTR_R,R2      ;Set data pointer to DQ1EXP
  329.         MOVE    #COEF_R,R6          ;Set coef pointer to B1
  330.         JSR     <PRDICT             ;(FMULT,ACCUM)
  331.         MOVE    B,Y:SEZ_R
  332.         MOVE    A,Y:SE_R
  333.  
  334.         MOVE    X:AP_R,A
  335.         MOVE    Y:YL_R,Y1
  336.         MOVE    Y:YU_R,Y0
  337.         JSR     <LIMAMIX            ;(LIMA,MIX)
  338.         MOVE    X1,X:AL_R
  339.         MOVE    A,X:Y_R
  340.  
  341. ;********************************************
  342. ; Get decoder ADPCM input
  343.  
  344.         MOVEP   X:PBD,X1
  345.         MOVE    Y:LSHFT-16,Y0
  346.         MPY     X1,Y0,A     #<$F0,X0    ;Shift to MSB's of A0
  347.         MOVE    A0,A
  348.         AND     X0,A                ;ADPCM bits in MSB's of A1
  349.         MOVE    A,X:I_R             ;Save decoder input
  350.  
  351. ;********************************************
  352.  
  353.         MOVE    X:Y_R,B
  354.         JSR     <IQUAN              ;(RECONST,ADDA,ANTILOG)
  355.         MOVE    A1,X:DQ_R
  356.  
  357.         MOVE    Y:TD_R,A
  358.         MOVE    Y:YL_R,B
  359.         JSR     <TRANS              ;(TRANS)
  360.         MOVE    A1,Y:TR_R
  361.  
  362.         MOVE    Y:SE_R,B
  363.         MOVE    X:DQ_R,A
  364.         MOVE    Y:SEZ_R,X0
  365.         MOVE    #PK1_R,R0
  366.         JSR     <ADDBC              ;(ADDB,ADDC)
  367.         MOVE    B1,Y:SIGPK_R
  368.         MOVE    X1,Y:SR_R
  369.  
  370.         MOVE    Y:LAW,B
  371.         JSR     <COMPRESS           ;(COMPRESS)
  372.  
  373. ;********************************************
  374. ; Save PCM decoder output (reconstructed signal)
  375.  
  376.         MOVE    A1,Y:SP_R
  377.  
  378. ;********************************************
  379.  
  380.         MOVE    X:DQ_R,Y0
  381.         JSR     <UPB                ;(XOR,UPB)
  382.  
  383.         MOVE    Y:SIGPK_R,X0
  384.         JSR     <UPA2               ;(UPA2,LIMC)
  385.         MOVE    A,Y:A2P_R
  386.         MOVE    A,Y:(R6)-
  387.  
  388.         MOVE    Y:SIGPK_R,X1
  389.         MOVE    Y:A2P_R,X0
  390.         JSR     <UPA1               ;(UPA1,LIMD)
  391.  
  392.         MOVE    X:DQ_R,A
  393.         MOVE    Y:SR_R,B
  394.         JSR     <FLOAT              ;(FLOATA,FLOATB)
  395.  
  396.         MOVE    Y:A2P_R,B
  397.         MOVE    Y:TR_R,Y0
  398.         JSR     <TONE               ;(TONE,TRIGB)
  399.         MOVE    Y1,Y:TDP_R
  400.         MOVE    A,Y:TD_R
  401.  
  402.         MOVE    Y:DMS_R,Y0
  403.         MOVE    Y:DML_R,Y1
  404.         JSR     <FUNCTF             ;(FUNCTF,FILTA,FILTB)
  405.         MOVE    A,Y:DMS_R
  406.         MOVE    B,Y:DML_R
  407.  
  408.         MOVE    Y:TDP_R,X1
  409.         MOVE    X:Y_R,Y1
  410.         JSR     <SUBTC              ;(SUBTC)
  411.  
  412.         MOVE    X:AP_R,X1
  413.         MOVE    Y:TR_R,Y1
  414.         JSR     <FILTC              ;(FILTC,TRIGA)
  415.         MOVE    A1,X:AP_R
  416.  
  417.         MOVE    X:Y_R,Y0
  418.         MOVE    Y:YL_R,Y1
  419.         JSR     <FUNCTW             ;(FUNCTW,FILTD,LIMB,FILTE)
  420.         MOVE    X0,Y:YU_R
  421.         MOVE    A1,Y:YL_R
  422.  
  423.         MOVE    R2,X:DATAPTR_R
  424.  
  425.         JMP     <IOWAIT
  426.  
  427. ;**************************************************************************
  428. ;       FMULT/ACCUM
  429. ;
  430. ; Perform adaptive prediction filter using 24-bit fixed point
  431. ; multiply and 56-bit accumulate
  432. ;
  433. ; SEZ(k) = [B1(k-1) * DQ(k-1)] + ... + [B6(k-1) * DQ(k-6)]
  434. ;        = WB1 + WB2 + ... + WB6
  435. ;
  436. ; SE(k) = SEZ(k) + [A1(k-1) * SR(k-1)] + [A2(k-1) * SR(k-2)]
  437. ;       = SEZ + WA1 + WA2
  438. ;
  439. ; Inputs:
  440. ;   SRn = X:(R2) = siii iiii | iiii iiii. | ffff ffff  (24TC)
  441. ;       (DQ in same format as SR)
  442. ;
  443. ;   An = Y:(R6) = si.ff ffff | ffff ffff | ffff ffff (24TC)
  444. ;       (Bn in same format as An)
  445. ;
  446. ; Outputs:
  447. ;   SEZ = siii iiii | iiii iiii. | ffff ffff  (24TC)
  448. ;   SE = siii iiii | iiii iiii. | ffff ffff  (24TC)
  449. ;
  450. ;**************************************************************************
  451.  
  452. PRDICT  CLR     A       X:(R2)+,X0  Y:(R6)+,Y0  ;Get DQ1 & B1
  453.         REP     #6
  454.         MAC     X0,Y0,A X:(R2)+,X0  Y:(R6)+,Y0  ;Find SEZ
  455.         TFR     A,B                             ;Copy SEZ
  456.         ASL     B                               ;Adjust radix pt.
  457.         MAC     X0,Y0,A X:(R2)+,X0  Y:(R6)+,Y0  ;Accum, get SR2 & A2
  458.         MAC     X0,Y0,A                         ;Find SE
  459.         ASL     A                               ;Adjust radix pt.
  460.         RTS
  461.  
  462. ;**************************************************************************
  463. ;       LIMA
  464. ;
  465. ; Limit speed control parameter
  466. ;
  467. ; AL(k) = 1        if AP(k-1) > 1
  468. ;       = AP(k-1)  if AP(k-1) <= 1
  469. ;
  470. ; Inputs:
  471. ;   AP = 0ii.f ffff | ffff ffff | ffff ffff  (23SM)
  472. ;
  473. ; Outputs:
  474. ;   AL = 0i.ff ffff | ffff ffff | ffff ffff  (23SM)
  475. ;
  476. ;**************************************************************************
  477.  
  478. LIMAMIX MOVE    #<$20,X0            ;Get '1'
  479.         CMP     X0,A                ;Test AP
  480.         TGT     X0,A                ;If AP>'1' set AL='1'
  481.         ASL     A                   ;Shift to align radix pt.
  482.  
  483. ;**************************************************************************
  484. ;       MIX
  485. ;
  486. ; Form linear combination of fast and slow quantizer
  487. ;   scale factors
  488. ;
  489. ; Y(k) = AL(k) * YU(k-1) + [1 - AL(k)] * YL(k-1)
  490. ;
  491. ; Inputs:
  492. ;   YL = 0iii i.fff | ffff ffff | ffff ffff  (23SM)
  493. ;   AL = 0i.ff ffff | ffff ffff | ffff ffff  (23SM)
  494. ;   YU = 0iii i.fff | ffff ffff | ffff ffff  (23SM)
  495. ;
  496. ; Outputs:
  497. ;   Y = 0iii i.fff | ffff ffff | ffff ffff  (23SM)
  498. ;
  499. ;**************************************************************************
  500.  
  501.         TFR     Y0,A    A,X1        ;Swap YU and AL
  502.         SUB     Y1,A                ;Find YU-YL
  503.         ABS     A       A,B         ;Find |YU-YL|, save sign
  504.         MOVE    A,Y0
  505.         MPY     X1,Y0,A             ;Find PRODM=|YU-YL|*AL
  506.         NEG     A   A,X0            ;Find -PRODM, save PRODM
  507.         TST     B   Y1,B            ;Check sign
  508.         TPL     X0,A                ;If sign=0 PROD=PRODM,
  509.                                     ; else PROD=-PRODM
  510.         ADDL    B,A                 ;Find Y=PROD+YL
  511.         RTS
  512.  
  513. ;**************************************************************************
  514. ;       EXPAND
  515. ;
  516. ; Convert A-law or mu-law PCM to uniform PCM (according to
  517. ;   Recommendation G.711). For further details see Motorola
  518. ;   application bulletin "Logarithmic/Linear Conversion
  519. ;   Routines for DSP56000/1".
  520. ;
  521. ; Input:
  522. ;   S = psss qqqq | 0000 0000 | 0000 0000 (PCM log format)
  523. ;
  524. ; Output:
  525. ;   SL = siii iiii | iiii ii.00 | 0000 0000  (14TC)
  526. ;
  527. ;**************************************************************************
  528.  
  529. CONVERT MOVE    A,X0    #>$80,Y1    ;Get shift constant
  530.         MPY     X0,Y1,A     #>$7F,X1    ;Shift S to 8 lsb's of A1
  531.         AND     X1,A                ;Mask off sign of S
  532.         MOVE    A1,N3               ;Load |S| as offset
  533.         CMPM    Y1,A                ;Check sign of S
  534.         MOVE    X:(R3+N3),A         ;Lookup |SL| from ROM table
  535.         JGE     <SUBTA              ;If S=0, SL=|SL|
  536.         NEG     A                   ;If S=1, SL=-|SL|
  537.  
  538. ;**************************************************************************
  539. ;       SUBTA
  540. ;
  541. ; Compute difference signal by subtracting signal estimate
  542. ;       from input signal
  543. ;
  544. ;   D(k) = SL(k) - SE(k)
  545. ;
  546. ; Inputs:
  547. ;   SL = siii iiii | iiii ii.00 | 0000 0000  (16TC) 
  548. ;   SE = siii iiii | iiii iiii. | ffff ffff  (24TC)
  549. ;
  550. ; Output:
  551. ;   D = siii iiii | iiii iiii. | ffff ffff  (24TC)
  552. ;**************************************************************************
  553.  
  554. SUBTA   ASR     A                       ;Sign extend SL and
  555.         SUBR    B,A                     ; find D=SL-SE
  556.  
  557. ;**************************************************************************
  558. ;       LOG
  559. ;
  560. ; Convert difference signal from the linear to the log
  561. ;   domain.  Use approximation LOG2[1 + x] = x
  562. ;
  563. ; Input:
  564. ;   D = siii iiii | iiii iiii. | ffff ffff  (24TC)
  565. ;
  566. ; Outputs:
  567. ;   DL = 0iii i.fff | ffff ffff | ffff ffff  (23SM)
  568. ;   DS = sXXX XXXX | XXXX XXXX | XXXX XXXX  (1TC)
  569. ;
  570. ;**************************************************************************
  571.  
  572.         ABS     A   A,Y1                ;Find DQM=|D|, save DS to Y1
  573.         MOVE    Y:RSHFT+15,X0           ;Get '1'
  574.         CMP     X0,A    #<$40,X1        ;Check for DQM<1
  575.         JGE     <NORMEXP
  576.         CLR     A                       ;If DQM<1 set DL=0
  577.         JMP     <SUBTB                  ; and continue
  578. NORMEXP
  579.         MOVE    #$000E,R0               ;Get exp bias (14)
  580.         REP     #14                     ;If DQM!=0, do norm iteration
  581.         NORM    R0,A                    ; 14 times to find MSB of DQM
  582.         EOR     X1,A    Y:LSHFT-19,X0   ;Zero MSB of MANT, get EXP shift
  583.         MOVE    R0,X1                   ;Move EXP to X1
  584.         MPY     X0,X1,A     A,X1        ;Shift EXP<<19, save MANT to X1
  585.         MOVE    Y:RSHFT+3,X0            ;Get shift
  586.         MOVE    A0,A                    ;Move EXP to A1
  587.         MAC     X0,X1,A                 ;Shift MANT>>3 & combine with EXP
  588.  
  589. ;**************************************************************************
  590. ;       SUBTB
  591. ;
  592. ; Scale log version of difference signal by subtracting
  593. ;   scale factor
  594. ;
  595. ; DLN(k) = DL(k) - Y(k)
  596. ;
  597. ; Inputs:
  598. ;   DL = 0iii i.fff | ffff ffff | ffff ffff  (23SM)
  599. ;   Y = 0iii i.fff | ffff ffff | ffff ffff  (23SM)
  600. ;
  601. ; Output:
  602. ;   DLN = siii i.fff | ffff ffff | ffff ffff  (24TC)
  603. ;
  604. ;**************************************************************************
  605.  
  606. SUBTB   SUB     Y0,A                    ;Find DLN=DL-Y
  607.  
  608. ;**************************************************************************
  609. ;       QUAN
  610. ;
  611. ; Quantize difference signal in log domain
  612. ;
  613. ;    log2|D(k)| - Y(k) | |I(k)|
  614. ;    ------------------+--------
  615. ;      [3.12, + inf)   |   7
  616. ;      [2.72, 3.12)    |   6
  617. ;      [2.34, 2.72)    |   5
  618. ;      [1.91, 2.34)    |   4
  619. ;      [1.38, 1.91)    |   3
  620. ;      [0.62, 1.38)    |   2
  621. ;      [-0.98, 0.62)   |   1
  622. ;      (- inf, -0.98)  |   0
  623. ;
  624. ; Inputs:
  625. ;   DLN = siii i.fff | ffff ffff | ffff ffff  (24TC)
  626. ;   DS = sXXX XXXX | XXXX XXXX | XXXX XXXX  (1TC)
  627. ;
  628. ; Output:
  629. ;   I = siii 0000 | 0000 0000 | 0000 0000 (ADPCM format)
  630. ;
  631. ;**************************************************************************
  632.  
  633.         MOVE    #QUANTAB,R0         ;Get quantization table base
  634.         MOVE    #>QUANTAB+2,X1      ;Get offset for quan conversion
  635.         MOVE    X:(R0)+,X0          ;Get quan table value
  636. TSTDLN  CMP     X0,A    X:(R0)+,X0  ;Compare to DLN
  637.         JGE     <TSTDLN             ;If value<DLN try next range
  638.         MOVE    R0,A                ;When range found...
  639.                                     ; subtract pointer from
  640.         SUB     X1,A    Y:LSHFT-20,X0   ; base to get IMAG=|I|  
  641.         MOVE    A1,X1
  642.         MPY     X0,X1,A     Y1,B    ;Shift IMAG <<20, result is
  643.                                     ; in A0, move DS (from LOG) into B
  644.         MOVE    A0,A
  645.         TST     A       #<$F0,X0    ;Check IMAG, get invert mask
  646.         JEQ     <INVERT             ;If IMAG=0 invert bits
  647.         TST     B                   ;If IMAG!=0, check DS
  648.         JPL     <IOUT               ;If DS=1 don't invert IMAG
  649. INVERT  EOR     X0,A                ;If DS=0 or IMAG=0 invert IMAG
  650. IOUT    MOVE    A1,A                ;Adjust sign extension
  651.         RTS
  652.  
  653. ;**************************************************************************
  654. ;       RECONST
  655. ;
  656. ; Reconstruct quantized difference signal in the log domain
  657. ;
  658. ;     |I(k)| | log2|DQ(k)| - Y(k)
  659. ;    --------+-------------------
  660. ;       7    |      3.32
  661. ;       6    |      2.91
  662. ;       5    |      2.52
  663. ;       4    |      2.13
  664. ;       3    |      1.66
  665. ;       2    |      1.05
  666. ;       1    |      0.031
  667. ;       0    |      - inf
  668. ;
  669. ; Inputs:
  670. ;   I = iiii 0000 | 0000 0000 | 0000 0000  (ADPCM format)
  671. ;
  672. ; Output:
  673. ;   DQLN = siii i.fff | ffff 0000 | 0000 0000  (12TC)
  674. ;   DQS = sXXX 0000 | 0000 0000 | 0000 0000  (1TC)
  675. ;   IMAG = 0000 0000 | 0000 0000 | 0000 0iii.
  676. ;
  677. ;**************************************************************************
  678.  
  679. IQUAN   MOVE    A,Y1                ;Save DQS (sign of I) to Y1
  680.         MOVE    #<$F0,X1
  681.         EOR     X1,A    Y:RSHFT+20,Y0   ;Invert bits of I
  682.         TMI     Y1,A                ;If ^IS=1, use I, else use ^I
  683.         MOVE    A1,X0
  684.         MPY     X0,Y0,A     #IQUANTAB,R0    ;Shift IMAG>>20
  685.         MOVE    A1,N0               ;Load IMAG as offset into IQUAN table
  686.         MOVE    A1,X:IMAG           ;Save |I|
  687.         MOVE    X:(R0+N0),A         ;Lookup DQLN
  688.  
  689. ;**************************************************************************
  690. ;       ADDA
  691. ;
  692. ; Add scale factor to log version of quantized difference
  693. ;   signal
  694. ;
  695. ; DQL(k) = DQLN(k) + Y(k)
  696. ;
  697. ; Inputs:
  698. ;   Y = 0iii i.fff | ffff ffff | ffff ffff  (23SM)
  699. ;   DQLN = siii i.fff | ffff 0000 | 0000 0000  (12TC)
  700. ;
  701. ; Output:
  702. ;   DQL = siii i.fff | ffff ffff | ffff ffff  (24TC)
  703. ;
  704. ;**************************************************************************
  705.  
  706.         ADD     B,A                 ;Find DQL=DQLN+Y
  707.    
  708. ;**************************************************************************
  709. ;       ANTILOG
  710. ;
  711. ; Convert quantized difference signal from log to linear
  712. ;   domain. Use approximation 2**(x) = 1 + x
  713. ;
  714. ; Input:
  715. ;   DQL = siii i.fff | ffff ffff | ffff ffff  (24TC)
  716. ;   DQS = sXXX 0000 | 0000 0000 | 0000 0000  (1TC)
  717. ;
  718. ; Outputs:
  719. ;   DQ = siii iiii | iiii iii.f | ffff ffff  (24SM)
  720. ;
  721. ;**************************************************************************
  722.  
  723.         JPL     <CONVLOG            ;If DQL>=0 convert DQL,
  724.                                     ; else DQL<0, set |DQ|=0
  725.         TFR     Y1,A    #<$80,X0    ;Get DQS (MSB of I), get mask
  726.         AND     X0,A    #0,B        ;Mask off DQS, set |DQ|=0
  727.         MOVE    B1,Y:DQMAG          ;Save DQMAG=|DQ|
  728.         JMP     <SAVEDQ
  729.  
  730. CONVLOG
  731.         TFR     A,B     #$07FFFF,X0 ;Get mask
  732.         AND     X0,A    #<$08,X1    ;Find fractional part (DMN), get '1'
  733.         OR      X1,A    #<$78,X0    ;Add '1' to DMN to find DQT,
  734.                                     ; get integer mask
  735.         AND     X0,B    Y:RSHFT+19,Y0   ;Find integer part (DEX),
  736.                                     ; get shift constant
  737.         MOVE    B1,X0
  738.         MPY     X0,Y0,B     #>$0A,X0    ;Shift DEX>>19, get '10'
  739.         SUB     X0,B        #$7FFFFF,X0 ;Find DQT shift=DEX-10
  740.         JEQ     <TRUNCDQM           ;If DEX=10, no shift
  741.         JLT     <SHFRDQ             ;If DEX<10, shift right
  742.         REP     B1                  ;Else shift DQT left
  743.         LSL     A                   ; up to 4 times
  744.         JMP     <TRUNCDQM
  745.  
  746. SHFRDQ  NEG     B       #RSHFT,R0   ;Find 10-DEX
  747.         MOVE    B1,N0               ;Use 10-DEX for shift lookup
  748.         MOVE    A1,Y0
  749.         MOVE    Y:(R0+N0),X1        ;Lookup shift constant
  750.         MPY     X1,Y0,A             ;Shift DQT right up to 9 times
  751. TRUNCDQM    AND X0,A    #<$80,B     ;Truncate to find DQMAG=|DQ|,
  752.                                     ; get sign mask
  753.         AND     Y1,B    A1,Y:DQMAG  ;Mask off DQS, save DQMAG           
  754.         MOVE    B1,X0
  755.         OR      X0,A                ;Add DQS to DQMAG to get DQ
  756.                                     ;Note: result in A1, not A
  757. SAVEDQ  RTS
  758.  
  759. ;**************************************************************************
  760. ;       TRANS
  761. ;
  762. ; Transition detector
  763. ;
  764. ; TR(k) = 1 if TD(k)=1 and |DQ(k)|> 24 x 2**(YL(k))
  765. ;         0 otherwise
  766. ;
  767. ; Inputs:
  768. ;   TD = i000 0000 | 0000 0000 | 0000 0000  (1TC)
  769. ;   YL = 0iii i.fff | ffff ffff | ffff ffff  (23SM)
  770. ;   DQ = siii iiii | iiii iii.f | ffff ffff  (24SM)
  771. ;
  772. ; Output:
  773. ;   TR = i000 0000 | 0000 0000 | 0000 0000  (1TC)
  774. ;
  775. ;**************************************************************************
  776.  
  777. TRANS   TST     A   #0,A            ;Check TD, set TR=0
  778.         JEQ     <SAVETR             ;If TD=0 save TR=0
  779.                                     ; else test DQ and YL
  780.         TFR     B,A     #$07FFFF,X0 ;Save YL, get mask
  781.         AND     X0,A    #<$08,X0    ;Find YLFRAC (YL>>10), get '1'
  782.         OR      X0,A    B,X1        ;Add implied '1' to YLFRAC,
  783.         MOVE    Y:RSHFT+19,Y1       ;Get shift const
  784.         MPY     Y1,X1,B     #>$08,X0    ;Find YLINT=YL>>19, get '8'
  785.         MOVE    B1,B                ;Clear fractional portion
  786.         CMP     X0,B    #>$05,X0    ;Compare YLINT to '8', get '5'
  787.         JGT     <MAXTHR             ;If YLINT>8 set maximum THR2
  788.         SUB     X0,B                ;Find YLINT-5
  789.         JEQ     <SETDQTHR           ;If YLINT=5 don't shift
  790.         JLT     <RSHIFT             ;If YLINT<5 shift right
  791.  
  792.         REP     B1                  ;Else shift YLFRAC left
  793.         LSL     A                   ; up to 3 times to get THR1
  794.         JMP     <SETDQTHR
  795.  
  796. MAXTHR  MOVE    #<$7C,A             ;Set maximum THR1
  797.         JMP     <SETDQTHR
  798.  
  799. RSHIFT  NEG     B       #RSHFT,R0   ;Find 5-YLINT
  800.         MOVE    B1,N0               ;Use 5-YLINT for shift lookup
  801.         MOVE    A1,X0
  802.         MOVE    Y:(R0+N0),X1        ;Lookup shift constant
  803.         MPY     X0,X1,A             ;Shift YLFRAC right up to 5 times
  804.                                     ; to get THR1
  805. SETDQTHR    TFR     A,B             ;Copy THR1=2**(YL)
  806.         ADDR    B,A     #0,X1
  807.         ASR     A       Y:DQMAG,X0  ;Find DQTHR='24' x 2**(YL)
  808.         CMP     X0,A    #<$80,A     ;Compare DQMAG to DQTHR, set TR=1
  809.         TGT     X1,A                ;If DQMAG>DQTHR leave TR=1,
  810.                                     ; else DQMAG<=DQTHR, set TR=0
  811. SAVETR  RTS
  812.  
  813. ;**************************************************************************
  814. ;       ADDB
  815. ;
  816. ; Add quantized difference signal and signal estimate
  817. ;   to form reconstructed signal
  818. ;
  819. ; SR(k-n) = SE(k-n) + DQ(k-n)
  820. ;
  821. ; Inputs:
  822. ;   DQ = siii iiii | iiii iii.f | ffff ffff  (24SM)
  823. ;   SE = siii iiii | iiii iiii. | ffff ffff  (24TC)
  824. ;
  825. ; Output:
  826. ;   SR = siii iiii | iiii iiii. | ffff ffff  (24TC)
  827. ;
  828. ;**************************************************************************
  829.  
  830. ADDBC   TST     A       Y:DQMAG,A   ;Check DQS, get DQMAG
  831.         JPL     <SHFTDQ             ;If DQS=0 continue
  832.         NEG     A                   ;Convert DQ to 2's comp
  833. SHFTDQ  ADDR    B,A     A,B         ;Find SR=DQ+SE, save DQ
  834.         TFR     B,A     A,X1        ;Swap DQ and SR
  835.  
  836. ;**************************************************************************
  837. ;       ADDC
  838. ;
  839. ; Obtain sign of addition of the quantized difference
  840. ;   signal and the partial signal estimate
  841. ;
  842. ; P(k) = DQ(k) + SEZ(k)
  843. ; PK0 = sign of P(k)
  844. ;
  845. ; Inputs:
  846. ;   DQ = siii iiii | iiii iii.0 | 0000 0000  (15SM)
  847. ;   SEZ = siii iiii | iiii iiii. | ffff ffff (24TC)
  848. ;
  849. ; Output:
  850. ;   PK0 = sXXX XXXX | XXXX XXXX | XXXX XXXX  (1TC)
  851. ;   SIGPK = i000 0000 | 0000 0000 | 0000 0000  (1TC)
  852. ;
  853. ;**************************************************************************
  854.  
  855.         ADD     X0,A    #0,B        ;Find DQSEZ=DQ+SEZ,
  856.                                     ; set SIGPK=0
  857.         TST     A   #<$80,X0        ;Check DQSEZ, get '1'
  858.         TEQ     X0,B                ;If DQSEZ=0, SIGPK=1,
  859.                                     ; else SIGPK=0
  860.         MOVE    Y:(R0)-,Y1          ;Get PK1
  861.         MOVE    Y:(R0)+,X0          ;Get PK0
  862.         MOVE    X0,Y:(R0)-          ;Delay previous PK0
  863.         EOR     X0,A    A1,Y:(R0)   ;Save new PK0, find PKS1=PK0**PK1
  864.                                     ; for UPA1 & UPA2
  865.         MOVE    A1,X:PKS1           ;Save PKS1
  866.         MOVE    Y:(R0),A
  867.         EOR     Y1,A                ;Find PKS2=PK0**PK2 for UPA2
  868.         MOVE    A1,X:PKS2           ;Save PKS2
  869.         RTS
  870.  
  871. ;**************************************************************************
  872. ;       XOR/UPB
  873. ;
  874. ; Update the coefficients of the sixth order predictor
  875. ;
  876. ; Bn(k) = [1-(2**-8)] * Bn(k-1)
  877. ;           + (2**-7) * sgn[DQ(k)] * sgn[DQ(k-n)]
  878. ; Un = sgn[DQ(k)] XOR sgn[DQ(k-n)]
  879. ;
  880. ; Inputs:
  881. ;   Bn = Y:(R6+n) = si.ff ffff | ffff ffff | ffff ffff (24TC)
  882. ;   DQ = siii iiii | iiii iii.f | ffff ffff (24SM)
  883. ;
  884. ; Outputs:
  885. ;   BnP = Y:(R6+n) = si.ff ffff | ffff ffff | ffff ffff (24TC)
  886. ;
  887. ;**************************************************************************
  888.  
  889. UPB     MOVE    Y:DQMAG,B
  890.         MOVE    #$008000,X0         ;Get +gain
  891.         DO      #6,ENDUPB           ;Do UPB and XOR for B1-B6
  892.         MOVE    X:(R2)+,A       Y:(R6),Y1   ;Get Bn & DQnS
  893.         EOR     Y0,A    #$FF8000,X1 ;Find Un=DQS**DQnS (XOR),
  894.                                     ; get -gain
  895.         TPL     X0,A                ;If Un=0 set UGBn=+gain
  896.         TMI     X1,A                ;If Un=1 set UGBn=-gain
  897.         TST     B       #0,X1       ;Test for |DQ|=0
  898.         TEQ     X1,A                ;If |DQ|=0, Then UGBn=0
  899.         MOVE    Y:RSHFT+8,X1        ;Get shift constant
  900.         MAC     -X1,Y1,A            ;Find UBn=UGBn-(Bn>>8)
  901.         ADD     Y1,A                ;Find BnP=Bn+UBn
  902.         MOVE    A1,Y:(R6)+          ;Store BnP to Bn
  903. ENDUPB  RTS
  904.  
  905. ;**************************************************************************
  906. ;       UPA2
  907. ;
  908. ; Update the A2 coefficient of the second order predictor.
  909. ;
  910. ; A2(k) = [1-(2**-7)] * A2(k-1)
  911. ;           + (2**-7) * { sgn[P(k)] * sgn[P(k-2)]
  912. ;               - F[A1(k-1)] * sgn[P(k)] * sgn[P(k-1)] }
  913. ;
  914. ; F[A1(k)] = 4 * A1       if |A1|<=(2**-1)
  915. ;          = 2 * sgn(A1)  if |A1|>(2**-1)
  916. ;
  917. ; Inputs:
  918. ;   A1 = Y:(R6) = si.ff ffff | ffff ffff | ffff ffff (24TC)
  919. ;   A2 = Y:(R6+1) = si.ff ffff | ffff ffff | ffff ffff (24TC)
  920. ;   SIGPK = i000 0000 | 0000 0000 | 0000 0000  (1TC)
  921. ;   PK0 = sXXX XXXX | XXXX XXXX | XXXX XXXX  (1TC)
  922. ;   PK1 = sXXX XXXX | XXXX XXXX | XXXX XXXX  (1TC)
  923. ;   PK2 = sXXX XXXX | XXXX XXXX | XXXX XXXX  (1TC)
  924. ;     (Note: PKS1 & PKS2 have been previously calculated)
  925. ;
  926. ; Outputs:
  927. ;   A2T = si.ff ffff | ffff ffff | ffff ffff (24TC)
  928. ;
  929. ;**************************************************************************
  930.  
  931. UPA2    MOVE    X:PKS2,A            ;Get PKS2=PK0**PK2
  932.         MOVE    #<$10,Y0            ;Get '+1'
  933.         TST     A   #<$F0,Y1        ;Check PKS2, get '-1'
  934.         TPL     Y0,A                ;If PKS2=0, set UGA2A='+1'
  935.         TMI     Y1,A                ;If PKS2=1, set UGA2A='-1'
  936.         MOVE    A,X1    Y:(R6)+,A   ;Save UGA2A, get A1
  937.         MOVE    #$1FFF00,Y0         ;Get '+1.99'
  938.         CMP     Y0,A    #$E00100,Y1 ;Check A1, get '-1.99'
  939.         TGT     Y0,A                ;If A1>=1/2, set FA1='1.99'
  940.         CMP     Y1,A    X:PKS1,B    ;Check A1 again, get PKS1=PK0**PK1
  941.         TLT     Y1,A                ;If A1<=-1/2, set FA1='-1.99'
  942.         TST     B                   ;Check PKS1
  943.         JMI     <FINDSUM            ;If PKS1=1, FA=FA1
  944.         NEG     A                   ; else PKS1=0, set FA=-FA1
  945. FINDSUM ADD     X1,A    Y:RSHFT+5,Y1    ;Find UGA2B=UGA2A+FA
  946.         TFR     X0,B    A,X1
  947.         MPY     X1,Y1,A     #0,X0   ;Find UGA2B>>7
  948.         TST     B   Y:(R6),Y0       ;Check SIGPK, get A2
  949.         TMI     X0,A                ;If SIGPK=1, set UGA2=0
  950.         MOVE    Y:RSHFT+7,X0        ;Get shift constant
  951.         MAC     -Y0,X0,A            ;Find UA2=UGA2-(A2>>7)
  952.         ADD     Y0,A                ;Find A2T=A2+UA2
  953.  
  954. ;**************************************************************************
  955. ;       LIMC
  956. ;
  957. ; Limit the A2 coefficient of the second order predictor.
  958. ;
  959. ;   |A2(k)| <= '0.75' 
  960. ;
  961. ; Inputs:
  962. ;   A2T = si.ff ffff | ffff ffff | ffff ffff (24TC)
  963. ;
  964. ; Outputs:
  965. ;   A2P = Y:(R6) = si.ff ffff | ffff ffff | ffff ffff (24TC)
  966. ;
  967. ;**************************************************************************
  968.  
  969.         MOVE    #<$D0,X0            ;Get A2LL
  970.         CMP     X0,A    #<$30,X1    ;Check A2P, get A2UL
  971.         TLT     X0,A                ;If A2P<-0.75, set A2P=-0.75
  972.         CMP     X1,A                ;Check A2P again
  973.         TGT     X1,A                ;If A2P>0.75, set A2P=0.75
  974.         RTS
  975.  
  976. ;**************************************************************************
  977. ;       UPA1
  978. ;
  979. ; Update the A1 coefficient of the second order predictor.
  980. ;
  981. ; A1(k) = [1-(2**-8)] * A1(k-1)
  982. ;           + 3 * (2**-8) * sgn[P(k)] * sgn[P(k-1)]
  983. ;
  984. ; Inputs:
  985. ;   A1 = Y:(R6) = si.ff ffff | ffff ffff | ffff ffff (24TC)
  986. ;   SIGPK = Y:(R0) = i000 0000 | 0000 0000 | 0000 0000  (1TC)
  987. ;   PK0 = sXXX XXXX | XXXX XXXX | XXXX XXXX  (1TC)
  988. ;   PK1 = sXXX XXXX | XXXX XXXX | XXXX XXXX  (1TC)
  989. ;     (Note: PKS1 has been previously calculated)
  990. ;
  991. ; Outputs:
  992. ;   A1T = si.ff ffff | ffff ffff | ffff ffff (24TC)
  993. ;
  994. ;**************************************************************************
  995.  
  996. UPA1    MOVE    #$00C000,Y0         ;Get +gain
  997.         MOVE    X:PKS1,B            ;Get PKS1=PK0**PK1
  998.         TST     B       #$FF4000,Y1 ;Check PKS1, get -gain
  999.         TPL     Y0,A                ;If PKS=0, set UGA1=+gain
  1000.         TMI     Y1,A                ;If PKS=1, set UGA1=-gain
  1001.         MOVE    X1,B
  1002.         TST     B       #0,X1       ;Check SIGPK
  1003.         TMI     X1,A                ;If SIGPK=1, set UGA1=0
  1004.         MOVE    Y:(R6),X1           ;Get A1
  1005.         MOVE    Y:RSHFT+8,Y0        ;Get shift constant
  1006.         MAC     -Y0,X1,A            ;Find UA1=UGA1-(A1>>8)
  1007.         ADD     X1,A                ;Find A1T=A1+UA1
  1008.  
  1009. ;**************************************************************************
  1010. ;       LIMD
  1011. ;
  1012. ; Limit the A1 coefficient of the second order predictor.
  1013. ;
  1014. ;   |A1(k)| <= [1-(2**-4)] - A2(k)
  1015. ;
  1016. ; Inputs:
  1017. ;   A1T = si.ff ffff | ffff ffff | ffff ffff (24TC)
  1018. ;   A2P = si.ff ffff | ffff ffff | ffff ffff (24TC)
  1019. ;
  1020. ; Outputs:
  1021. ;   A1P = Y:(R6) = si.ff ffff | ffff ffff | ffff ffff (24TC)
  1022. ;
  1023. ;**************************************************************************
  1024.  
  1025.         MOVE    #<$3C,B             ;Get OME='1-(2**-4)'
  1026.         SUB     X0,B                ;Find A1UL=OME-A2P
  1027.         CMP     B,A     B,X0        ;Check A1T
  1028.         TGT     X0,A                ;If A1T>A1UL, set A1P=A1UL
  1029.         NEG     B       #2,N6       ;Find A1LL=-A1UL=A2P-OME
  1030.         CMP     B,A     B,X0        ;Check A1T again
  1031.         TLT     X0,A                ;If A1T<A1LL, set A1P=A1LL
  1032.         MOVE    A1,Y:(R6)+N6        ;Store A1P to A1
  1033.         RTS
  1034.  
  1035. ;**************************************************************************
  1036. ;       FLOATA
  1037. ;
  1038. ; Convert the quantized difference signal from signed magnitude
  1039. ;   to two's complement and save to the data buffer.
  1040. ;
  1041. ; Inputs:
  1042. ;   DQ = siii iiii | iiii iii.f | ffff ffff (24SM)
  1043. ;
  1044. ; Outputs:
  1045. ;   DQ = X:(R2) = siii iiii | iiii iiii. | ffff ffff (24TC)
  1046. ;
  1047. ;**************************************************************************
  1048.  
  1049. FLOAT   TST     A       #2,N2       ;Test sign of DQ
  1050.         JPL     <TRUNCDQ
  1051.         MOVE    Y:DQMAG,A           ;If DQ<0,
  1052.         NEG     A                   ; negate magnitude of DQ
  1053. TRUNCDQ ASR     A       (R2)+       ;Sign extend to 16TC
  1054.         MOVE    A,X:(R2)-N2
  1055.  
  1056. ;**************************************************************************
  1057. ;       FLOATB
  1058. ;
  1059. ; Save the reconstructed signal to the data buffer.
  1060. ;
  1061. ; Inputs:
  1062. ;   SR = siii iiii | iiii iiii. | ffff ffff  (24TC)
  1063. ;
  1064. ; Outputs:
  1065. ;   SR = X:(R2) = siii iiii | iiii iiii. | ffff ffff  (24TC)
  1066. ;
  1067. ;**************************************************************************
  1068.  
  1069.         MOVE    B,X:(R2)+N2
  1070.         RTS
  1071.  
  1072. ;**************************************************************************
  1073. ;       TONE
  1074. ;
  1075. ; Partial band signal detection
  1076. ;
  1077. ; TD(k) = 1 if A2(k) < -0.71875
  1078. ;         0 otherwise
  1079. ;
  1080. ; Inputs:
  1081. ;   A2P = si.ff ffff | ffff ffff | ffff ffff  (24TC)
  1082. ;
  1083. ; Output:
  1084. ;   TDP = i000 0000 | 0000 0000 | 0000 0000  (1TC)
  1085. ;
  1086. ;**************************************************************************
  1087.  
  1088. TONE    CLR     A   #<$D2,X0        ;Get '-.71875', set TDP=0
  1089.         CMP     X0,B    #<$80,X1    ;Check A2P, get '1'
  1090.         TLT     X1,A                ;If A2P<-.71875 set TDP=1, else TDP=0
  1091.  
  1092. ;**************************************************************************
  1093. ;       TRIGB
  1094. ;
  1095. ; Predictor trigger block
  1096. ;
  1097. ; If TR(k) = 1, An(k)=Bn(k)=TD(k)=0
  1098. ;
  1099. ; Inputs:
  1100. ;   TR = i000 0000 | 0000 0000 | 0000 0000  (1TC)
  1101. ;   BnP = si.ff ffff | ffff ffff | ffff ffff  (24TC)
  1102. ;   AnP = si.ff ffff | ffff ffff | ffff ffff  (24TC)
  1103. ;   TDP = i000 0000 | 0000 0000 | 0000 0000  (1TC)
  1104. ;
  1105. ; Output:
  1106. ;   BnR = si.ff ffff | ffff ffff | ffff ffff  (24TC)
  1107. ;   AnR = si.ff ffff | ffff ffff | ffff ffff  (24TC)
  1108. ;   TDR = i000 0000 | 0000 0000 | 0000 0000  (1TC)
  1109. ;
  1110. ;**************************************************************************
  1111.  
  1112.         MOVE    Y0,B
  1113.         TST     B       A,Y1        ;Test TR
  1114.         JEQ     <ENDTRIG
  1115.         CLR     A                   ;If TR=1, set TDR=0,
  1116.         REP     #8                  ; and B1-B6,A1,A2=0
  1117.         MOVE    A,Y:(R6)+
  1118. ENDTRIG RTS
  1119.  
  1120. ;**************************************************************************
  1121. ;       FUNCTF
  1122. ;
  1123. ; Maps quantizer output I into F(I) function
  1124. ;
  1125. ;  |I(k)|  | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
  1126. ; ---------+---+---+---+---+---+---+---+---+
  1127. ;  F[I(k)] | 7 | 3 | 1 | 1 | 1 | 0 | 0 | 0 |
  1128. ;
  1129. ; Inputs:
  1130. ;   I = siii. 0000 | 0000 0000 | 0000 0000
  1131. ;
  1132. ; Output:
  1133. ;   FI = 0iii. 0000 | 0000 0000 | 0000 0000  (3SM)
  1134. ;
  1135. ;**************************************************************************
  1136.  
  1137. FUNCTF  MOVE    #FIBASE,R0          ;Load lookup table base
  1138.         MOVE    X:IMAG,N0           ;Load IMAG as offset
  1139.         NOP
  1140.         MOVE    X:(R0+N0),A         ;Get FI from lookup table
  1141.  
  1142. ;**************************************************************************
  1143. ;       FILTA
  1144. ;
  1145. ; Update short term average of F(I)
  1146. ;
  1147. ; DMS(k) = (1 - 2**(-5)) * DMS(k-1) + 2**(-5) * F[I(k)]
  1148. ;
  1149. ; Inputs:
  1150. ;   FI = 0iii. 0000 | 0000 0000 | 0000 0000  (3SM)
  1151. ;   DMS = 0iii. ffff | ffff ffff | ffff ffff  (23SM)
  1152. ;
  1153. ; Output:
  1154. ;   DMSP = 0iii. ffff | ffff ffff | ffff ffff  (23SM)
  1155. ;
  1156. ;**************************************************************************
  1157.  
  1158.         SUB     Y0,A    A,B         ;Find DIF=FI-DMS, save FI
  1159.         TFR     Y0,A    A,X0        ;Move DIF and DMS
  1160.         MOVE    Y:RSHFT+5,X1        ;Get mask
  1161.         MAC     X0,X1,A             ;Find DMSP=(DIF>>5)+DMS
  1162.  
  1163. ;**************************************************************************
  1164. ;       FILTB
  1165. ;
  1166. ; Update long term average of F(I)
  1167. ;
  1168. ; DML(k) = (1 - 2**(-7)) * DML(k-1) + 2**(-7) * F[I(k)]
  1169. ;
  1170. ; Inputs:
  1171. ;   FI = 0iii. 0000 | 0000 0000 | 0000 0000  (3SM)
  1172. ;   DML = 0iii. ffff | ffff ffff | ffff ffff  (23SM)
  1173. ;
  1174. ; Output:
  1175. ;   DMLP = 0iii. ffff | ffff ffff | ffff ffff  (23SM)
  1176. ;
  1177. ;**************************************************************************
  1178.  
  1179.         SUB     Y1,B    Y:RSHFT+7,X1    ;Find DIF=FI-DML
  1180.         TFR     Y1,B    B,X0
  1181.         MAC     X0,X1,B             ;Find DMLP=(DIF>>7)+DML
  1182.         RTS
  1183.  
  1184. ;**************************************************************************
  1185. ;       SUBTC
  1186. ;
  1187. ; Compute magnitude of the difference of short and long
  1188. ;  term functions of quantizer output sequence and then
  1189. ;  perform threshold comparison for quantizing speed control
  1190. ;  parameter.
  1191. ;
  1192. ; AX = 1  if Y(k)>=3, TD(k)=1, & |DMS(k)-DML(k)|>(2**-3)*DML(k)
  1193. ;    = 0  otherwise
  1194. ;
  1195. ; Input:
  1196. ;   Y = 0iii i.fff | ffff ffff | ffff ffff  (23SM)
  1197. ;   DMSP = 0iii. ffff | ffff ffff | ffff ffff  (23SM)
  1198. ;   DMLP = 0iii. ffff | ffff ffff | ffff ffff  (23SM)
  1199. ;   TDP = i000 0000 | 0000 0000 | 0000 0000  (1TC)
  1200. ;
  1201. ; Output:
  1202. ;   AX = 0i0.0 0000 | 0000 0000 | 0000 0000  (1SM)
  1203. ;
  1204. ;**************************************************************************
  1205.  
  1206. SUBTC   SUB     B,A     Y:RSHFT+3,X0    ;Find DIF=DMSP-DMLP
  1207.         ABS     A       B,Y0        ;Find DIFM=|DIF|
  1208.         MPY     X0,Y0,B     #<$40,X0    ;Find DTHR=DMLP>>3, get '1'
  1209.         CMP     B,A     #0,B        ;Compare DIFM & DTHR, set AX=0
  1210.         TGE     X0,B                ;If DIFM>=DTHR set AX=1
  1211.         MOVE    X1,A                ;Get TDP
  1212.         TST     A       #<$18,Y0    ;Check TDP, get '3'
  1213.         TNE     X0,B                ;If TDP!=0 set AX=1
  1214.         MOVE    Y1,A
  1215.         CMP     Y0,A                ;Check for Y<"3"
  1216.         TLT     X0,B                ;If Y<"3" set AX=1
  1217.         RTS
  1218.  
  1219. ;**************************************************************************
  1220. ;       FILTC
  1221. ;
  1222. ; Low pass filter of speed control parameter
  1223. ;
  1224. ; AP(k) = (1-2**(-4)) * AP(k-1) + AX
  1225. ;
  1226. ; Inputs:
  1227. ;   AX = 0i0.0 0000 | 0000 0000 | 0000 0000  (1SM)
  1228. ;   AP = 0ii.f ffff | ffff ffff | ffff ffff  (23SM)
  1229. ;
  1230. ; Outputs:
  1231. ;   APP = 0ii.f ffff | ffff ffff | ffff ffff  (23SM)
  1232. ;
  1233. ;**************************************************************************
  1234.  
  1235. FILTC   SUB     X1,B    Y:RSHFT+4,Y0    ;Find DIF=AX-AP
  1236.         TFR     X1,A    B,X0
  1237.         MAC     X0,Y0,A                 ;Find APP=(DIF>>4)+AP
  1238.  
  1239. ;**************************************************************************
  1240. ;       TRIGA
  1241. ;
  1242. ; Speed control trigger block
  1243. ;
  1244. ; AP(k) = AP(k) if TR(k)=0
  1245. ;       =  1    if TR(k)=1
  1246. ;
  1247. ; Inputs:
  1248. ;   TR = i000 0000 | 0000 0000 | 0000 0000  (1TC)
  1249. ;   APP = 0ii.f ffff | ffff ffff | ffff ffff  (23SM)
  1250. ;
  1251. ; Outputs:
  1252. ;   APR = 0ii.f ffff | ffff ffff | ffff ffff  (23SM)
  1253. ;
  1254. ;**************************************************************************
  1255.  
  1256.         MOVE    Y1,B
  1257.         TST     B       #<$20,X0    ;Check TR, get '1'
  1258.         TMI     X0,A                ;If TR=1 set APR=1, else APR=APP
  1259.         RTS
  1260.  
  1261. ;**************************************************************************
  1262. ;       FUNCTW
  1263. ;
  1264. ; Map quantizer output into logarithmic version of scale
  1265. ;  factor multiplier
  1266. ;
  1267. ;  |I(k)|  |  7  |  6  |  5  |  4  |  3  |  2  |  1  |  0  |
  1268. ; ---------+-----+-----+-----+-----+-----+-----+-----+-----+
  1269. ;   W(I)   |70.13|22.19|12.38| 7.00| 4.00| 2.56| 1.13|-0.75|
  1270. ;
  1271. ; Inputs:
  1272. ;   I = siii. 0000 | 0000 0000 | 0000 0000
  1273. ;
  1274. ; Outputs:
  1275. ;   WI = siii iiii. | ffff 0000 | 0000 0000  (12TC)
  1276. ;
  1277. ;**************************************************************************
  1278.  
  1279. FUNCTW  MOVE    #WIBASE,R0          ;Load lookup table base
  1280.         MOVE    X:IMAG,N0           ;Load IMAG as offset
  1281.         NOP
  1282.         MOVE    X:(R0+N0),A         ;Get WI from lookup table
  1283.  
  1284. ;**************************************************************************
  1285. ;       FILTD
  1286. ;
  1287. ; Update of fast quantizer scale factor
  1288. ;
  1289. ; YU(k) = (1 - 2**(-5)) * Y(k) + 2**(-5) * W[I(k)]
  1290. ;
  1291. ; Inputs:
  1292. ;   WI =  siii iiii. | ffff 0000 | 0000 0000  (12TC)
  1293. ;   Y = 0iii i.fff | ffff ffff | ffff ffff  (23SM)
  1294. ;
  1295. ; Outputs:
  1296. ;   YUT = 0iii i.fff | ffff ffff | ffff ffff  (23SM)
  1297. ;
  1298. ;**************************************************************************
  1299.  
  1300.         MOVE    Y:RSHFT+3,X1        ;Get shift constant
  1301.         MAC     -Y0,X1,A    Y0,B    ;Find DIF=WI-(Y>>3)
  1302.         ASR     A
  1303.         ADDR    B,A                 ;Find YUT=(DIF>>5)+Y (actually DIF>>2)
  1304.  
  1305. ;**************************************************************************
  1306. ;       LIMB
  1307. ;
  1308. ; Limit quantizer scale factor
  1309. ;
  1310. ; 1.06 <= YU(k) <= 10.00
  1311. ;
  1312. ; Inputs:
  1313. ;   YUT = 0iii i.fff | ffff ffff | ffff ffff  (23SM)
  1314. ;
  1315. ; Outputs:
  1316. ;   YUP = 0iii i.fff | ffff ffff | ffff ffff  (23SM)
  1317. ;
  1318. ;**************************************************************************
  1319.  
  1320.         MOVE    #<$50,X0            ;Get upper limit '10'
  1321.         CMP     X0,A    #$088000,X1 ;Check for YU>10,
  1322.                                     ; get lower limit '1.06'
  1323.         TGT     X0,A                ;If YU>10 set YU=10
  1324.         CMP     X1,A                ;Check for YU<1.06
  1325.         TLT     X1,A                ;If YU<1.06 set YU=1.06
  1326.         MOVE    A,X0                ;Save YUP
  1327.  
  1328. ;**************************************************************************
  1329. ;       FILTE
  1330. ;
  1331. ; Update of slow quantizer scale factor
  1332. ;
  1333. ; YL(k) = (1 - 2**(-6)) * YL(k-1) + 2**(-6) * YU(k)
  1334. ;
  1335. ; Inputs:
  1336. ;   YUP = 0iii i.fff | ffff ffff | ffff ffff  (23SM)
  1337. ;   YL = 0iii i.fff | ffff ffff | ffff ffff  (23SM)
  1338. ;
  1339. ; Outputs:
  1340. ;   YLP = 0iii i.fff | ffff ffff | ffff ffff  (23SM)
  1341. ;
  1342. ;**************************************************************************
  1343.  
  1344.         MOVE    Y1,B
  1345.         SUB     B,A     Y:RSHFT+6,Y0    ;Find DIF=YUP-YL
  1346.         TFR     B,A     A,X1
  1347.         MAC     Y0,X1,A                 ;Find YLP=(DIFSX>>6)+YL
  1348.         RTS
  1349.  
  1350. ;**************************************************************************
  1351. ;       COMPRESS
  1352. ;
  1353. ; Convert from uniform PCM to A-law or mu-law PCM (according to
  1354. ;   Recommendation G.711). For further details see Motorola
  1355. ;   application bulletin "Logarithmic/Linear Conversion
  1356. ;   Routines for DSP56000/1".
  1357. ;
  1358. ; Input:
  1359. ;   SR = siii iiii | iiii iiii. | 0000 0000  (16TC)
  1360. ;
  1361. ; Output:
  1362. ;   SP = psss qqqq | 0000 0000 | 0000 0000 (PCM log format)
  1363. ;
  1364. ;**************************************************************************
  1365.  
  1366. COMPRESS
  1367.         MOVE    #$002100,Y0         ;Get bias
  1368.         TST     B       X1,A
  1369.         JNE     <ALAW
  1370.  
  1371. ; Linear to log routine for mu-law
  1372.         ABS     A       A,B         ;Find |SR|, save sign
  1373.         ADD     Y0,A                ;Add bias
  1374.         ASL     A   #TAB+7,R0       ;Shift << 2, get seg ptr
  1375.         ASL     A   X:TAB+3,X0      ; and get max. word
  1376.         TES     X0,A                ;If overflow in extension
  1377.                                     ; set the maximum PCM word
  1378.         REP     #7                  ;Find MSB of data
  1379.         NORM    R0,A
  1380.         ASL     A       #<$20,Y0
  1381.         LSL     B       A1,X0
  1382.         MPY     X0,Y0,A     X:(R0),X1
  1383.         AND     X1,A
  1384.         ROR     A
  1385.         NOT     A       #<$FF,X0
  1386.         AND     X0,A
  1387.         MOVE    A1,A
  1388.         JMP     <SAVESP
  1389.  
  1390. ; Linear to log routine for A-law
  1391. ALAW    MOVE    #$FFFF00,X0
  1392.         AND     X0,A
  1393.         ABS     A       A,B         ;Find |SR|, save sign
  1394.         TST     B       #$000100,X0
  1395.         JPL     <NOSUB
  1396.         SUB     X0,A
  1397. NOSUB   MOVE    #$7FFE00,X0
  1398.         AND     X0,A
  1399.         ASL     A   #TAB+7,R0       ;Shift << 2, get seg ptr
  1400.         ASL     A   X:TAB+3,X0      ; and get max. word
  1401.         TES     X0,A                ;If overflow in extension
  1402.                                     ; set the maximum PCM word
  1403.         REP     #6                  ;Find MSB of data
  1404.         NORM    R0,A
  1405.         JNR     <SEGOK
  1406.         MOVE    (R0)-
  1407. SEGOK   LSL     A       #<$20,Y0
  1408.         LSL     B       A1,X0
  1409.         MPY     X0,Y0,A     X:(R0),X1
  1410.         AND     X1,A
  1411.         ROR     A       #<$D5,Y1
  1412.         EOR     Y1,A    #<$FF,X0    ;Invert even bits & sign
  1413.         AND     X0,A
  1414.         MOVE    A1,A
  1415. SAVESP  RTS
  1416.  
  1417. ;**************************************************************************
  1418. ;       INIT
  1419. ;
  1420. ; Initialize program variables, transfer data tables to X and Y
  1421. ; memory, and set up registers
  1422. ;
  1423. ;**************************************************************************
  1424.  
  1425. INIT    MOVE    A,R0
  1426.         REP     #$7F                ;Clear internal data RAM
  1427.         MOVE    A,L:(R0)+
  1428.  
  1429. ; X memory initialization
  1430.  
  1431.         MOVE    #DATA_T,A0          ;Set transmit data pointer
  1432.         MOVE    A0,X:DATAPTR_T      ; to start of transmit data buffer
  1433.         MOVE    #DATA_R,A0          ;Set receive data pointer
  1434.         MOVE    A0,X:DATAPTR_R      ; to start of receive data buffer
  1435.  
  1436.         MOVE    #$3E2000,X0
  1437.         MOVE    X0,X:AP_T           ;Initialize speed control parameters
  1438.         MOVE    X0,X:AP_R
  1439.  
  1440.         MOVE    #VARINIT,R0         ;Copy constant tables into
  1441.         MOVE    #QUANTAB,R3         ; X memory
  1442.         DO      #40,XTABLES
  1443.         MOVE    P:(R0)+,X0
  1444.         MOVE    X0,X:(R3)+
  1445. XTABLES
  1446.  
  1447. ; Y memory initialization
  1448.  
  1449.         MOVE    #$088000,X0
  1450.         MOVE    X0,Y:YU_T           ;Initialize quantizer scale factors
  1451.         MOVE    X0,Y:YL_T
  1452.         MOVE    X0,Y:YU_R
  1453.         MOVE    X0,Y:YL_R
  1454.  
  1455.         MOVE    #RSHFT,R3           ;Copy shift constant table into
  1456.         DO      #24,YTABLES         ; Y memory
  1457.         MOVE    P:(R0)+,X0
  1458.         MOVE    X0,Y:(R3)+
  1459. YTABLES
  1460.  
  1461.         MOVEC   #7,M2               ;Set data buffer for mod(7)
  1462.         MOVEC   #7,M6               ;Set coef buffer for mod(7)
  1463.         MOVEC   #$7F,M3             ;Set PCM table for mod(127)
  1464.         MOVE    #0,A                ;Select mu-law or A-law,
  1465.         MOVE    A,Y:LAW             ; for mu-law set LAW=0 (default),
  1466.                                     ; for A-law set LAW!=0
  1467.         TST     A       #$100,R3    ;If LAW=0 select mu-law table
  1468.         JEQ     <IOINIT             ; base (in X ROM), otherwise
  1469.         MOVE    #$180,R3            ; select A-law table base
  1470.  
  1471. IOINIT  MOVEP   #$00000F,X:PBD      ;Initialize PB0..3
  1472.         MOVEP   #$00000F,X:PBDDR    ;Set PB0..3 for outputs
  1473.  
  1474.         MOVEP   #$003200,X:CRB      ;Set up SSI mode
  1475.         MOVEP   #$000000,X:CRA      ;Set up SSI rate
  1476.         MOVEP   #$0001E0,X:PCC      ;Enable SSI output pins
  1477.         MOVEP   #0,X:SSITX          ;Dummy write to SSI transmitter
  1478.         RTS
  1479.  
  1480. ; QUANTAB
  1481. VARINIT     DC      $F84000         ;-0.98
  1482.             DC      $050000         ;0.62
  1483.             DC      $0B2000         ;1.38
  1484.             DC      $0F6000         ;1.91
  1485.             DC      $12C000         ;2.34
  1486.             DC      $15D000         ;2.72
  1487.             DC      $190000         ;3.12
  1488.             DC      $7FFFFF         ;15.99
  1489.  
  1490. ; IQUANTAB
  1491.             DC      $800000         ;-16    |I|=0
  1492.             DC      $004000         ;0.031  |I|=1
  1493.             DC      $087000         ;1.05   |I|=2
  1494.             DC      $0D5000         ;1.66   |I|=3
  1495.             DC      $111000         ;2.13   |I|=4
  1496.             DC      $143000         ;2.52   |I|=5
  1497.             DC      $175000         ;2.91   |I|=6
  1498.             DC      $1A9000         ;3.32   |I|=7
  1499.  
  1500. ; WIBASE
  1501.             DC      $FF4000         ;-0.75  |I|=0
  1502.             DC      $012000         ;1.13   |I|=1
  1503.             DC      $029000         ;2.56   |I|=2
  1504.             DC      $040000         ;4.00   |I|=3
  1505.             DC      $070000         ;7.00   |I|=4
  1506.             DC      $0C6000         ;12.38  |I|=5
  1507.             DC      $163000         ;22.19  |I|=6
  1508.             DC      $462000         ;70.13  |I|=7
  1509.  
  1510. ; FIBASE
  1511.             DC      $000000         ;0  |I|=0
  1512.             DC      $000000         ;0  |I|=1
  1513.             DC      $000000         ;0  |I|=2
  1514.             DC      $100000         ;1  |I|=3
  1515.             DC      $100000         ;1  |I|=4
  1516.             DC      $100000         ;1  |I|=5
  1517.             DC      $300000         ;3  |I|=6
  1518.             DC      $700000         ;7  |I|=7
  1519.  
  1520. ; TAB
  1521.             DC      $1E0000
  1522.             DC      $3E0000
  1523.             DC      $5E0000
  1524.             DC      $7E0000
  1525.             DC      $9E0000
  1526.             DC      $BE0000
  1527.             DC      $DE0000
  1528.             DC      $FE0000
  1529.  
  1530. ; RSHFT
  1531.             DC      $800000
  1532.             DC      $400000         ;>>1    <<23
  1533.             DC      $200000         ;>>2    <<22
  1534.             DC      $100000         ;>>3    <<21
  1535.             DC      $080000         ;>>4    <<20
  1536.             DC      $040000         ;>>5    <<19
  1537.             DC      $020000         ;>>6    <<18
  1538.             DC      $010000         ;>>7    <<17
  1539.             DC      $008000         ;>>8    <<16
  1540.             DC      $004000         ;>>9    <<15
  1541.             DC      $002000         ;>>10   <<14
  1542.             DC      $001000         ;>>11   <<13
  1543.             DC      $000800         ;>>12   <<12
  1544.             DC      $000400         ;>>13   <<11
  1545.             DC      $000200         ;>>14   <<10
  1546.             DC      $000100         ;>>15   <<9
  1547.             DC      $000080         ;>>16   <<8
  1548.             DC      $000040         ;>>17   <<7
  1549.             DC      $000020         ;>>18   <<6
  1550.             DC      $000010         ;>>19   <<5
  1551.             DC      $000008         ;>>20   <<4
  1552.             DC      $000004         ;>>21   <<3
  1553.             DC      $000002         ;>>22   <<2
  1554.             DC      $000001         ;>>23   <<1
  1555.